#!/usr/bin/env python3
"""
解释为什么在 PEP 517 构建中看到 egg_info 而不是 build/install
"""

def explain_egg_info_in_pep517():
    """解释 egg_info 命令在 PEP 517 中的作用"""
    
    print("🔍 为什么 setup.py 收到的是 'egg_info' 而不是 'build'/'install'？")
    print("=" * 70)
    
    print("""
📋 PEP 517 构建过程中的不同阶段：

1️⃣  元数据收集阶段 (你看到的这个)：
    sys.argv = ['_in_process.py', 'egg_info']
    
    目的：
    ✓ 收集包的基本信息 (name, version, dependencies)
    ✓ 生成 .egg-info 目录
    ✓ 为后续构建提供元数据
    ✓ 不实际编译任何代码

2️⃣  实际构建阶段 (稍后会发生)：
    sys.argv = ['_in_process.py', 'build_ext', '--inplace']
    或
    sys.argv = ['_in_process.py', 'bdist_wheel']
    
    目的：
    ✓ 编译 C 扩展
    ✓ 构建 wheel 文件
    ✓ 这时会调用你的 CMakeBuild

3️⃣  安装阶段：
    pip 直接安装构建好的 wheel，不再调用 setup.py
    """)

def show_pep517_workflow():
    """展示完整的 PEP 517 工作流程"""
    
    print("\n🔄 完整的 pip install -e . 工作流程：")
    print("-" * 50)
    
    workflow = [
        ("1. 元数据发现", "egg_info", "获取包名、版本、依赖等基本信息"),
        ("2. 依赖解析", "不调用setup.py", "pip 解析并安装构建依赖"),
        ("3. 准备元数据", "egg_info", "再次确认元数据，准备构建"),
        ("4. 构建 wheel", "build_ext + bdist_wheel", "编译扩展，打包 wheel"),
        ("5. 安装", "不调用setup.py", "pip 安装 wheel 到环境"),
    ]
    
    for step, command, description in workflow:
        print(f"   {step:15} -> {command:20} | {description}")
    
    print(f"\n💡 你看到的是第1步或第3步！")

def explain_why_egg_info():
    """解释为什么需要 egg_info"""
    
    print(f"\n🥚 为什么需要 'egg_info' 命令？")
    print("-" * 40)
    
    print("""
egg_info 命令的作用：
┌─────────────────────────────────────┐
│  收集项目元数据信息                      │
├─────────────────────────────────────│
│  ✓ 包名 (name)                      │
│  ✓ 版本 (version)                   │
│  ✓ 依赖列表 (install_requires)        │
│  ✓ 入口点 (entry_points)            │
│  ✓ 扩展模块 (ext_modules)            │
│  ✓ 数据文件 (package_data)           │
└─────────────────────────────────────┘

为什么先收集这些信息？
1. pip 需要知道依赖关系来解决冲突
2. 需要知道包名来创建正确的安装路径
3. 需要知道有哪些扩展模块需要编译
4. 这些信息不需要实际编译就能获得
    """)

def show_actual_build_stage():
    """展示实际构建阶段会看到什么"""
    
    print(f"\n🏗️  实际构建阶段 (当你的 CMakeBuild 运行时)：")
    print("-" * 55)
    
    print("""
在构建 C 扩展时，你会看到类似：
sys.argv = ['_in_process.py', 'build_ext', '--inplace']

或者在打包时：
sys.argv = ['_in_process.py', 'bdist_wheel', '--dist-dir', './dist']

这时候：
✓ CMakeBuild.run() 会被调用
✓ CMakeBuild.build_extension() 会执行
✓ 你的 CMAKE 编译会开始
✓ C 扩展会被真正编译
    """)

def explain_in_process_py():
    """解释 _in_process.py 的作用"""
    
    print(f"\n🔧 _in_process.py 是什么？")
    print("-" * 30)
    
    print("""
_in_process.py 是 pip 的构建协调器：
┌─────────────────────────────────────┐
│  pip 的 pyproject_hooks 包中的脚本    │
├─────────────────────────────────────│
│  作用：                             │
│  ✓ 隔离构建环境                      │
│  ✓ 协调 PEP 517 构建后端           │
│  ✓ 传递参数给 setuptools           │
│  ✓ 收集构建结果                      │
└─────────────────────────────────────┘

调用链：
pip → _in_process.py → setuptools.build_meta → exec(setup.py)

所以 setup.py 看到的 sys.argv[0] 是 _in_process.py
    """)

def main():
    explain_egg_info_in_pep517()
    show_pep517_workflow()
    explain_why_egg_info()
    show_actual_build_stage()
    explain_in_process_py()
    
    print(f"\n" + "=" * 70)
    print("✅ 总结你看到的情况：")
    print("   1. egg_info 是正常的 - 这是元数据收集阶段")
    print("   2. 实际的 C 扩展编译会在后续的 build_ext 阶段") 
    print("   3. _in_process.py 是 pip 的构建协调器，不是错误")
    print("   4. 整个过程是 PEP 517 标准的正确实现")
    print("=" * 70)

if __name__ == "__main__":
    main() 